package com.ant.storage.service.impl;

import com.ant.storage.common.ResultCode;
import com.ant.storage.common.ResultVo;
import com.ant.storage.dto.DingDto;
import com.ant.storage.dto.PlannedDto;
import com.ant.storage.dto.PolicyDto;
import com.ant.storage.handler.AntException;
import com.ant.storage.mapper.GoodsPoolMapper;
import com.ant.storage.mapper.HistoricalProcurementMapper;
import com.ant.storage.mapper.PlannedMapper;
import com.ant.storage.mapper.SubscribeMapper;
import com.ant.storage.pojo.*;
import com.ant.storage.service.*;
import com.ant.storage.utils.DingDingUtil;
import com.ant.storage.utils.RandomUtil;
import com.ant.storage.vo.CommodityVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.taobao.api.ApiException;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author melon
 * @since 2022-11-07
 */
@Service
public class PlannedServiceImpl extends ServiceImpl<PlannedMapper, Planned> implements IPlannedService {


    @Autowired
    IGoodsPoolService goodsPoolService;

    @Autowired
    IGoodsPoolCommodityService goodsPoolCommodityService;

    @Autowired
    IPlannedService plannedService;

    @Autowired
    ISubscribeService subscribeService;

    @Resource
    SubscribeMapper subscribeMapper;

    @Autowired
    IPurchaseOrdersService purchaseOrdersService;

    @Autowired
    IAuditListService auditListService;

    @Resource
    private IHistoricalProcurementService historicalProcurementService;

    @Resource
    private IPlannedHistoricalProcurementService plannedHistoricalProcurementService;

    @Autowired
    IMergeSubscribeService mergeSubscribeService;

    @Resource
    GoodsPoolMapper goodsPoolMapper;

    @Resource
    HistoricalProcurementMapper historicalProcurementMapper;

    @Override
    public PageInfo<Planned> querylist(PlannedDto dto) {
        try {
            PageHelper.startPage(dto.getPageIndex(), dto.getPageSize());
            QueryWrapper<Planned> wrapper = new QueryWrapper<>();
            if (StringUtils.isNotEmpty(dto.getOddNumbers())) {
                wrapper.like("planned_number", dto.getOddNumbers());
            }
            if (dto.getTimes() != null && dto.getTimes().size() != 0) {
                wrapper.ge("creation_time", dto.getTimes().get(0) + " 00:00:00");
                wrapper.le("creation_time", dto.getTimes().get(1) + " 23:59:59");
            }
            wrapper.orderByDesc("id");
            List<Planned> planneds = this.baseMapper.selectList(wrapper);
            planneds.stream().map(item -> {
                List<Integer> byId = this.baseMapper.selectPlannedHistoricalProcurementById(item.getId());
                if (byId.size() != 0) {
                    item.setProcurementList(historicalProcurementMapper.selectList(new QueryWrapper<HistoricalProcurement>().in("id", byId).eq("is_cancel", 1)));
                }
                return item;
            }).collect(Collectors.toList());
            PageInfo<Planned> pageInfo = new PageInfo<>(planneds);
            return pageInfo;
        } catch (Exception e) {
            throw new AntException(ResultCode.BODY_NOT_MATCH);
        }
    }

    /**
     * 添加计划采购单
     *
     * @param dto
     * @param bindingResult
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo addPlan(PlannedDto dto, BindingResult bindingResult) {
                Planned planned = new Planned();
                BeanUtils.copyProperties(dto, planned);
                planned.setPlannedNumber(RandomUtil.getOrderNumbers(this.baseMapper.selectLastID()));
                planned.setCreationTime(new Date());
                this.baseMapper.insert(planned);

        //        if (dto.getCommodityList().size() > 0) {
        //            dto.getCommodityList().stream().map(item -> {
        //                historicalProcurement(item, planned.getId());
        //                return item;
        //            }).collect(Collectors.toList());
        //        } else {
        //            throw new AntException(ResultCode.PARAM_NOT_BLANK);
        //        }

        //          List<GoodsPoolCommodity> commodityList =
        //                            goodsPoolCommodityService.list(new QueryWrapper<GoodsPoolCommodity>()
        //                                    .in("id", dto.getIdsList()));
        //                    //数量乘以单价求和
        //                    BigDecimal sum = commodityList.stream().map(item -> {
        //                        // int转BigDecimal
        //                        BigDecimal commodityAmount = new BigDecimal(item.getCommodityAmount());
        //                        BigDecimal commodityPrice = item.getCommodityPrice();
        //                        return commodityAmount.multiply(commodityPrice);
        //                    }).reduce(BigDecimal.ZERO, BigDecimal::add);
        //                    // 生成采购单
        //                    Subscribe subscribe = new Subscribe();
        //                    subscribe.setParentId(goodsPool.getId());
        //                    subscribe.setCityId(goodsPool.getCityId());
        //                    subscribe.setDepartmentId(goodsPool.getDepartmentId());
        //
        //                    subscribe.setSubscribeNumber(RandomUtil.getOrderNumbers(subscribeMapper.selectLastID()));
        //                    subscribe.setPurchaseType(goodsPool.getApplyType().toString());
        //                    subscribe.setPurchaserId(dto.getUserId());
        //                    subscribe.setTotal(commodityList.size());
        //                    subscribe.setPrice(sum);
        //                    subscribe.setProcessState(2);
        //                    subscribe.setIsSettlement(0);
        //                    subscribe.setStatus("1");
        //                    subscribe.setProposerId(goodsPool.getProposerId());
        //                    subscribe.setCreatorBy(goodsPool.getCreatorBy());
        //                    subscribe.setCreationTime(new Date());
        //                    subscribeService.save(subscribe);
        //
        //                    GoodsPoolAndSubscribe goodsPoolAndSubscribe = new GoodsPoolAndSubscribe();
        //                    goodsPoolAndSubscribe.setSubscribeId(subscribe.getId());
        //                    goodsPoolAndSubscribe.setGoodsPoolId(goodsPool.getId());
        //                    goodsPoolAndSubscribeService.save(goodsPoolAndSubscribe);
        //
        //                    // 采购清单
        //                    List<PurchaseOrders> ordersList = commodityList.stream().map(item -> {
        //                        PurchaseOrders orders = new PurchaseOrders();
        //                        orders.setOrdersNumber(goodsPool.getSubscribeNumber().substring(2));
        //                        orders.setParentId(subscribe.getId());
        //                        orders.setDepartmentId(goodsPool.getDepartmentId());
        //                        orders.setGoodsPoolCommodityId(item.getId());
        //                        orders.setGoodsTotalPrice(new BigDecimal(item.getCommodityAmount()).multiply(item
        //                        .getCommodityPrice()));
        //                        orders.setGoodsStatus(0);
        //                        orders.setPurchaserId(dto.getUserId());
        //                        orders.setModifierBy("1");
        //                        orders.setCreationTime(new Date());
        //                        return orders;
        //                    }).collect(Collectors.toList());
        //                    purchaseOrdersService.saveBatch(ordersList);
        //
        //                    List<Integer> list = plannedHistoricalProcurementMapper.selectPolicyById(dto.getId(), dto
        //                    .getPlaList());
        //                    // 批量修改
        //                    plannedHistoricalProcurementService.update(new
        //                    UpdateWrapper<PlannedHistoricalProcurement>()
        //                            .set("policy_status", 1)
        //                            .in("id", list));
        //                    GoodsPool g = new GoodsPool();
        //                    Integer c = plannedHistoricalProcurementMapper.selectPolicy(dto.getId());
        //                    if (c == 0) {
        //                        g.setSplitting(1);
        //                    }
        //                    //修改采购池状态
        //                    g.setId(dto.getId());
        //                    g.setApplyStatus(2);
        //                    g.setStatus(2);
        //                    goodsPoolMapper.updateById(g);


        //
        //        Ability one = abilityService.getOne(new QueryWrapper<Ability>()
        //                .eq("ability_key", "Nail_Approval"));
        //        if (one != null && one.getIsOpen()) {
        //            AuditList auditList = new AuditList();
        //            auditList.setParentId(planned.getId());
        //            auditList.setProcessType("planPurchase");
        //            auditList.setCreationTime(new Date());
        //            // 添加审核记录
        //            for (String str : dto.getApproval()) {
        //                auditList.setNameId(str);
        //                auditList.setTypes("1");
        //                auditListService.save(auditList);
        //            }
        //            for (String str2 : dto.getNotify()) {
        //                auditList.setNameId(str2);
        //                auditList.setTypes("2");
        //                auditListService.save(auditList);
        //            }
        //            DingDto dtos = new DingDto();
        //            dtos.setOriginator_userid(dto.getUserId());
        //            dtos.setDeptId(dto.getDeptId());
        //            dtos.setId(planned.getId());
        //            dtos.setApprover_userid(dto.getApproval());
        //            dtos.setCc_userId(dto.getNotify());
        //            dtos.setList(dto.getCommodityList());
        //            dtos.setCity(dto.getCity());
        //            dtos.setDepartment(dto.getDepartment());
        //            dtos.setRemarks(dto.getRemarks());
        //
        //            try {
        //                String process_instance_id = addDingDing(dtos);
        //                System.out.println("process_instance_id = " + process_instance_id);
        //                UpdateWrapper<Planned> updateWrapper = new UpdateWrapper<Planned>().set(
        //                        "process_instance_id", process_instance_id)
        //                        .eq("id", planned.getId());
        //                this.update(updateWrapper);
        //                return ResultVo.success("提交成功");
        //            } catch (Exception e) {
        //                e.printStackTrace();
        //                return ResultVo.fail(e.getMessage());
        //            }
        return null;
        // }
        // return ResultVo.success("提交成功!!!");
    }

    /**
     * 提交钉钉审批
     *
     * @param dto
     * @return
     */
    @SneakyThrows
    @Transactional
    public String addDingDing(DingDto dto) throws ApiException {
        dto.setAccess_token(DingDingUtil.obtainToken());
        String process_instance_id = DingDingUtil.OldGoodeAppalyAndApprove(dto);
        System.out.println(process_instance_id);
        return process_instance_id;
    }

    /**
     * 计划采购通过添加采购池
     *
     * @param id
     * @return
     */
    @Override
    @Transactional()
    public ResultVo adoptPlannedApply(Integer id) {
        Planned planned = this.baseMapper.selectOne(new QueryWrapper<Planned>().eq("id", id));
        if (planned != null) {
            List<Integer> byId = this.baseMapper.selectPlannedHistoricalProcurementById(id);
            List<HistoricalProcurement> procurementList =
                    historicalProcurementService.list(
                            new QueryWrapper<HistoricalProcurement>().in("id", byId));
            //通过之后改成 0
            GoodsPool goodsPool = new GoodsPool();
            goodsPool.setSubscribeNumber("SQ" + RandomUtil.getOrderNumbers(goodsPoolMapper.selectLastID()));
            goodsPool.setCityId(planned.getCityId());
            goodsPool.setDepartmentId(planned.getDepartmentId());
            goodsPool.setPurchaserId(null);
            goodsPool.setApplyType(18);
            goodsPool.setApplyStatus(2);
            goodsPool.setStatus(0);
            goodsPool.setPrice(new BigDecimal("0"));
            goodsPool.setProposerId(Integer.valueOf(planned.getCreatorBy()));
            goodsPool.setCreatorBy(planned.getCreatorBy());
            goodsPool.setCreationTime(new Date());
            goodsPool.setProcessInstanceId(planned.getProcessInstanceId());
            goodsPoolMapper.insert(goodsPool);
            //
            if (procurementList.size() > 0) {
                List<GoodsPoolCommodity> goodsPoolCommodityList = procurementList.stream().map(item -> {
                    GoodsPoolCommodity commodity = new GoodsPoolCommodity();
                    commodity.setCommodityAmount(new BigDecimal( item.getCommodityAmount()));
                    commodity.setCommodityPrice(item.getCommodityPrice());
                    commodity.setCommodityId(item.getCommodityId());
                    commodity.setGoodsPoolId(goodsPool.getId());
                    return commodity;
                }).collect(Collectors.toList());
                goodsPoolCommodityService.saveBatch(goodsPoolCommodityList);
                plannedService.update(new UpdateWrapper<Planned>()
                        .set("goods_pool_id", goodsPool.getId())
                        .set("apply_status", 1)
                        .eq("id", id));
                return ResultVo.success("采购单已生成");
            } else {
                throw new AntException(ResultCode.NOT_FOUND);
            }
        } else {
            throw new AntException(ResultCode.NOT_FOUND);
        }

    }

    /**
     * 保存计划申请历史数据
     *
     * @param vo
     */
    public void historicalProcurement(CommodityVo vo, Integer id) {
        List<HistoricalProcurement> procurementList = historicalProcurementService.list(
                new QueryWrapper<HistoricalProcurement>().eq("commodity_id", vo.getCommodityId()));
        HistoricalProcurement procurement = new HistoricalProcurement();
        procurement.setCommodityId(vo.getCommodityId());
        procurement.setCommodityAmount(vo.getCommodityAmount());
        procurement.setCommodityPrice(vo.getCommodityPrice());
        procurement.setSupplierId(vo.getSupplierId());
        procurement.setPayType(vo.getPayType());
        procurement.setIsCancel(1);
        procurement.setChannel(vo.getChannel());
        procurement.setCreatorBy("admin");
        procurement.setCreationTime(new Date());

        PlannedHistoricalProcurement plannedHistoricalProcurement = new PlannedHistoricalProcurement();

        if (procurementList.size() > 0) {
            procurement.setId(procurementList.get(0).getId());
            plannedHistoricalProcurement.setHistoricalProcurementId(procurementList.get(0).getId());
            historicalProcurementService.updateById(procurement);
        } else {
            historicalProcurementService.save(procurement);
            plannedHistoricalProcurement.setHistoricalProcurementId(procurement.getId());
        }
        plannedHistoricalProcurement.setPlannedId(id);
        plannedHistoricalProcurementService.save(plannedHistoricalProcurement);
    }

    @Override
    public ResultVo getPlannedDetailsById(Integer id) {
        List<CommodityVo> plannedVos = this.baseMapper.plannedGoolPoolDetails(id);
        return ResultVo.success("获取成功", plannedVos);
    }

    /**
     * 分单生成采购单
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional()
    public ResultVo policyGenerateSubscribe(PolicyDto dto) {
        // 生成采购单
        Subscribe subscribe = subscribeMapper.selectOne(new QueryWrapper<Subscribe>().eq("id", dto.getId()));
        if (subscribe.getId() != null) {
            dto.getIdsList().stream().forEach(item -> {
                purchaseOrdersService.update(new UpdateWrapper<PurchaseOrders>()
                        .set("purchaser_id", dto.getUserId()).eq("id", item));
            });
            String user = subscribe.getPurchaserId() == null ? dto.getUserId().toString() :
                    subscribe.getPurchaserId() + "," + dto.getUserId();
            MergeSubscribe mergeSubscribe=new MergeSubscribe();
            mergeSubscribe.setSubscribeId(dto.getId());
            mergeSubscribe.setPurchaserId(dto.getUserId());
            mergeSubscribe.setStatus(0);
            mergeSubscribe.setHandlers("admin");
            mergeSubscribe.setCreationTime(new Date());
            mergeSubscribeService.save(mergeSubscribe);
            subscribeService.update(new UpdateWrapper<Subscribe>()
                    .set("purchaser_id", user).eq("id", dto.getId()));
            List<PurchaseOrders> list = purchaseOrdersService.list(new QueryWrapper<PurchaseOrders>()
                     .eq("parent_id", dto.getId()).isNotNull("purchaser_id"));
            if (list.size() == subscribe.getTotal()) {
                subscribeService.update(new UpdateWrapper<Subscribe>()
                        .set("is_merge", 1).eq("id", dto.getId()));
            }
            return ResultVo.success("分单成功");
        } else {
            return ResultVo.fail("不存在!!!");
        }
    }

    @Override
    public ResultVo getPolicySubscribe(Integer id) {
        return ResultVo.success("获取成功", this.baseMapper.getPolicySubscribeById(id));
    }

    @Override
    public ResultVo getPlannedProcurement(Integer warehouseId) {
        return ResultVo.success("获取成功", this.baseMapper.getPlannedProcurement(warehouseId));
    }
}
